/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.editors.support.ChildDelegate;
import cn.easyplatform.studio.web.editors.support.CodeFormatter;
import cn.easyplatform.studio.web.editors.support.ZulXsdUtil;
import cn.easyplatform.web.ext.echarts.ECharts;
import nu.xom.*;
import org.apache.commons.io.IOUtils;
import org.zkoss.util.resource.Locators;
import org.zkoss.zk.ui.*;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.SelectEvent;
import org.zkoss.zk.ui.sys.DesktopCtrl;
import org.zkoss.zkmax.zul.Chosenbox;
import org.zkoss.zul.*;
import org.zkoss.zul.impl.InputElement;

import java.io.IOException;
import java.util.*;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
class EchartView extends AbstractView<String> {

    private String scope;

    private Idspace canvas;

    private Grid grid;

    private Rows properties;

    private boolean isRepeat = true;

    private String content;//用于保存当前最新的标签内容

    private String zulMapXml;//用于保存当前最新的标签内容(含UUID)

    private Document document;//标签文本对象(用来转化为最新的标签内容)

    private Component echartComp;//由标签内容生成的echart对象

    private Element selection;//当前选中的echart部分标签对象(用来和document联动,保证标签文本对象内容为最新)

    private String componentType;//当前选中的是哪个类型的标签

    private String seriesIndex;//当选中的类型的标签为series时的记录第几个series的下标

    private Textbox id;//id

    private Textbox title;//标题

    private Combobox theme;//主题

    private Chosenbox toolbox;//工具

    private Textbox hflex;//横向权重

    private Textbox vflex;//纵向权重

    private Textbox top;//上间距占比

    private Textbox bottom;//下间距占比

    private Textbox left;//左间距占比

    private Textbox right;//右间距占比

    /**
     * @param cb
     */
    protected EchartView(EditorCallback<String> cb, String scope) {
        super(cb);
        this.scope = scope;
    }

    @Override
    protected void createContent(final Component parent) {
        Component c = Executions.createComponents(
                "~./include/views/echarts.zul", parent, null);
        for (Component comp : c.getFellows()) {
            if (comp.getId().equals("echart_grid_widget")) {
                grid = (Grid) comp;
            } else if (comp instanceof A) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp instanceof Button) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("echart_idspace")) {
                canvas = (Idspace) comp;
                if (scope.equals("bar")) {
                    initBar(c);
                } else if (scope.equals("line")) {

                } else if (scope.equals("pie")) {

                } else if (scope.equals("other")) {
                    initOther(c);
                }
            }
        }
    }

    private void initBar(Component c) {//初始化柱状图
        try {
            content = IOUtils.toString(Locators.getDefault()
                    .getResourceAsStream("web/template/" + "bar" + ".zul"), "utf-8");
            echartComp = Executions.createComponentsDirectly(content,
                    "zul", canvas, null);
            document = mapZulToComponents(content, echartComp);
            //echartComp.addEventListener(ECharts.ON_SELECTION, new BarEventListener());
            //下面是初始化基础属性布局
            properties = (Rows) c.getFellow("properties");
            Group modelGroup = properties.getGroups().get(1);
            Row row = new Row();
            Textbox textbox = new Textbox();
            row.appendChild(new Label("title"));
            textbox.setHflex("1");
            //textbox.setValue(((ECharts) echartComp).getTitle() != null ? ((ECharts) echartComp).getTitle() : "");
            textbox.addEventListener(Events.ON_CHANGE, this);
            row.appendChild(textbox);
            properties.insertBefore(row, modelGroup);
            row = new Row();
            row.appendChild(new Label("toolbox"));
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setValue(((ECharts) echartComp).getToolbox() != null ? ((ECharts) echartComp).getToolbox() : "");
            textbox.addEventListener(Events.ON_CHANGE, this);
            row.appendChild(textbox);
            properties.insertBefore(row, modelGroup);
            row = new Row();
            row.appendChild(new Label("hflex"));
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setValue(((ECharts) echartComp).getHflex() != null ? ((ECharts) echartComp).getHflex() : "");
            textbox.addEventListener(Events.ON_CHANGE, this);
            row.appendChild(textbox);
            properties.insertBefore(row, modelGroup);
            row = new Row();
            row.appendChild(new Label("vflex"));
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setValue(((ECharts) echartComp).getVflex() != null ? ((ECharts) echartComp).getVflex() : "");
            textbox.addEventListener(Events.ON_CHANGE, this);
            row.appendChild(textbox);
            properties.insertBefore(row, modelGroup);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initOther(Component c) {//初始化其他图
        content = cb.getValue();
        echartComp = Executions.createComponentsDirectly(content,
                "zul", canvas, null);
        document = mapZulToComponents(content, echartComp);
        //echartComp.addEventListener(ECharts.ON_SELECTION, new OtherEventListener());
        //下面是初始化基础属性布局
        properties = (Rows) c.getFellow("properties");
        Group modelGroup = properties.getGroups().get(1);
        Row row = new Row();
        Label label = new Label("id");
        label.setAttribute("property","id");
        row.appendChild(label);
        id = new Textbox();
        id.setHflex("1");
        id.setValue(((ECharts) echartComp).getId());
        id.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(id);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("标题");
        label.setAttribute("property","title");
        row.appendChild(label);
        title = new Textbox();
        title.setHflex("1");
        //title.setValue(((ECharts) echartComp).getTitle());
        title.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(title);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("主题");
        label.setAttribute("property","theme");
        row.appendChild(label);
        theme = new Combobox();
        theme.appendChild(new Comboitem("default"));
        theme.appendChild(new Comboitem("light"));
        theme.appendChild(new Comboitem("dark"));
        theme.appendChild(new Comboitem("vintage"));
        theme.appendChild(new Comboitem("infographic"));
        theme.appendChild(new Comboitem("macarons"));
        theme.appendChild(new Comboitem("roma"));
        theme.appendChild(new Comboitem("shine"));
        theme.setHflex("1");
        theme.setValue(((ECharts) echartComp).getTheme());
        theme.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(theme);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("工具");
        label.setAttribute("property","toolbox");
        row.appendChild(label);
        toolbox = new Chosenbox();
        toolbox.setHflex("1");
        toolbox.setCreatable(false);
        ListModelList<String> model = new ListModelList<String>();
        model.add("restore");
        model.add("saveAsImage");
        model.add("dataZoom");
        toolbox.setModel(model);
        String toolStr = ((ECharts) echartComp).getToolbox() != null ? ((ECharts) echartComp).getToolbox() : "";
        toolbox.setSelectedObjects(Arrays.asList(toolStr.split(";")));
        toolbox.addEventListener(Events.ON_SELECT, this);
        row.appendChild(toolbox);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("横向权重");
        label.setAttribute("property","hflex");
        row.appendChild(label);
        hflex = new Textbox();
        hflex.setHflex("1");
        hflex.setValue(((ECharts) echartComp).getHflex() != null ? ((ECharts) echartComp).getHflex() : "");
        hflex.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(hflex);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("纵向权重");
        label.setAttribute("property","vflex");
        row.appendChild(label);
        vflex = new Textbox();
        vflex.setHflex("1");
        vflex.setValue(((ECharts) echartComp).getVflex() != null ? ((ECharts) echartComp).getVflex() : "");
        vflex.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(vflex);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("上间距占比");
        label.setAttribute("property","top");
        row.appendChild(label);
        top = new Textbox();
        top.setHflex("1");
        top.setValue(((ECharts) echartComp).getTop() != null ? ((ECharts) echartComp).getTop() : "");
        top.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(top);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("下间距占比");
        label.setAttribute("property","bottom");
        row.appendChild(label);
        bottom = new Textbox();
        bottom.setHflex("1");
        //bottom.setValue(((ECharts) echartComp).getBottom() != null ? ((ECharts) echartComp).getBottom() : "");
        bottom.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(bottom);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("左间距占比");
        label.setAttribute("property","left");
        row.appendChild(label);
        left = new Textbox();
        left.setHflex("1");
        left.setValue(((ECharts) echartComp).getLeft() != null ? ((ECharts) echartComp).getLeft() : "");
        left.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(left);
        properties.insertBefore(row, modelGroup);
        row = new Row();
        label = new Label("右间距占比");
        label.setAttribute("property","right");
        row.appendChild(label);
        right = new Textbox();
        right.setHflex("1");
        //right.setValue(((ECharts) echartComp).getRight() != null ? ((ECharts) echartComp).getRight() : "");
        right.addEventListener(Events.ON_CHANGE, this);
        row.appendChild(right);
        properties.insertBefore(row, modelGroup);
    }

    private class BarEventListener implements EventListener<Event> {//柱状图的监听

        BarEventListener() {

        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getTarget() == echartComp) {// TODO: 2019/8/23 图表点击事件处理部分
                Map<String, Object> data = (Map<String, Object>) event.getData();
                if ("xAxis".equals(data.get("componentType"))) {
                    selection = getElementByUuid(echartComp.query("xAxis").getUuid());
                    componentType = "xAxis";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(xAxis)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Textbox textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("type") != null ? selection.getAttribute("type").getValue() : "");
                    // TODO: 2019/8/23 这种方式判断来获取最新的selection以后要改掉
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    row.appendChild(new Label("type"));
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("data") != null ? selection.getAttribute("data").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    row.appendChild(new Label("data"));
                    row.appendChild(textbox);
                    row.setParent(properties);
                } else if ("series".equals(data.get("componentType"))) {
                    Iterator<Component> a = echartComp.queryAll("series").iterator();
                    List<Component> series = new ArrayList<>();
                    while (a.hasNext()) {
                        series.add(a.next());
                    }
                    selection = getElementByUuid(series.get(Integer.valueOf(data.get("seriesIndex") + "")).getUuid());
                    componentType = "series";
                    seriesIndex = data.get("seriesIndex") + "";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(series)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Textbox textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("type") != null ? selection.getAttribute("type").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    row.appendChild(new Label("type"));
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("name") != null ? selection.getAttribute("name").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    row.appendChild(new Label("name"));
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("data") != null ? selection.getAttribute("data").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    row.appendChild(new Label("data"));
                    row.appendChild(textbox);
                    row.setParent(properties);
                }
            }
            if (event.getName().equals(Events.ON_CHANGE)) {
                String propertyName = null;
                Object value = null;
                propertyName = ((Label) event.getTarget().getPreviousSibling())
                        .getValue();
                value = ((InputElement) event.getTarget()).getRawValue();
                Attribute attribute = selection.getAttribute(propertyName);
                if (attribute == null && value.toString().length() > 0) {
                    Attribute uuid = selection.getAttribute("uuid");
                    selection.removeAttribute(uuid);
                    selection.addAttribute(new Attribute(propertyName, value
                            .toString()));
                    // 保证uuid属性在最后
                    selection.addAttribute(uuid);
                } else if (attribute != null && value.toString().length() > 0) {
                    if (value.equals(attribute.getValue()))
                        return;
                    attribute.setValue(value.toString());
                }
                //zulMapXml = CodeFormatter.formatXML(document);
                Document copy = (Document) document.copy();
                ZulXsdUtil.cleanUUIDs(copy.getRootElement());
                content = CodeFormatter.formatXML(copy);
                System.out.println(value);
                redraw();
                // TODO: 2019/8/23 这种方式判断来获取最新的selection以后要改掉
                if (Strings.isBlank(componentType)) {
                    return;
                }
                if (componentType.equals("xAxis")) {
                    selection = getElementByUuid(echartComp.query(componentType).getUuid());
                } else if (componentType.equals("series")) {
                    Iterator<Component> a = echartComp.queryAll(componentType).iterator();
                    List<Component> series = new ArrayList<>();
                    while (a.hasNext()) {
                        series.add(a.next());
                    }
                    selection = getElementByUuid(series.get(Integer.valueOf(seriesIndex)).getUuid());
                }
            }
        }
    }

    private class OtherEventListener implements EventListener<Event> {//其他图的监听

        OtherEventListener() {

        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getTarget() == echartComp) {// TODO: 2019/8/23 图表点击事件处理部分
                properties.getGroups().get(0).setOpen(false);
                Map<String, Object> data = (Map<String, Object>) event.getData();
                if ("xAxis".equals(data.get("componentType"))) {
                    selection = getElementByUuid(echartComp.query("xAxis").getUuid());
                    componentType = "xAxis";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(xAxis)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Combobox combobox = new Combobox();
                    combobox.appendChild(new Comboitem("category"));
                    combobox.appendChild(new Comboitem("value"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("type") != null ? selection.getAttribute("type").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    Label label = new Label("类型");
                    label.setAttribute("property","type");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    Textbox textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("dataArr") != null ? selection.getAttribute("dataArr").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("数据组");
                    label.setAttribute("property","dataArr");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("query") != null ? selection.getAttribute("query").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("查询语句");
                    label.setAttribute("property","query");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("pie_inner"));
                    combobox.appendChild(new Comboitem("pie_rich"));
                    combobox.appendChild(new Comboitem("axis_format_percent"));
                    combobox.appendChild(new Comboitem("axis_format_temperature"));
                    combobox.appendChild(new Comboitem("funnel_default_percent"));
                    combobox.appendChild(new Comboitem("funnel_inside_percent"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("labelClass") != null ? selection.getAttribute("labelClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("标签风格");
                    label.setAttribute("property","labelClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                }else if ("yAxis".equals(data.get("componentType"))) {
                    selection = getElementByUuid(echartComp.query("yAxis").getUuid());
                    componentType = "yAxis";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(yAxis)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Combobox combobox = new Combobox();
                    combobox.appendChild(new Comboitem("category"));
                    combobox.appendChild(new Comboitem("value"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("type") != null ? selection.getAttribute("type").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    Label label = new Label("类型");
                    label.setAttribute("property","type");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("pie_inner"));
                    combobox.appendChild(new Comboitem("pie_rich"));
                    combobox.appendChild(new Comboitem("axis_format_percent"));
                    combobox.appendChild(new Comboitem("axis_format_temperature"));
                    combobox.appendChild(new Comboitem("funnel_default_percent"));
                    combobox.appendChild(new Comboitem("funnel_inside_percent"));
                    combobox.appendChild(new Comboitem("bar_visible_top"));
                    combobox.appendChild(new Comboitem("bar_visible_bottom"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("labelClass") != null ? selection.getAttribute("labelClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("标签风格");
                    label.setAttribute("property","labelClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                }else if ("legend".equals(data.get("componentType"))) {
                    selection = getElementByUuid(echartComp.query("legend").getUuid());
                    componentType = "legend";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(legend)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Textbox textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("dataArr") != null ? selection.getAttribute("dataArr").getValue() : "");
                    // TODO: 2019/8/23 这种方式判断来获取最新的selection以后要改掉
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    Label label = new Label("数据组");
                    label.setAttribute("property","dataArr");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("query") != null ? selection.getAttribute("query").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("查询语句");
                    label.setAttribute("property","query");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    Combobox combobox = new Combobox();
                    combobox.appendChild(new Comboitem("vertical"));
                    combobox.appendChild(new Comboitem("horizontal"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("orient") != null ? selection.getAttribute("orient").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("方向");
                    label.setAttribute("property","orient");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("left"));
                    combobox.appendChild(new Comboitem("right"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("x") != null ? selection.getAttribute("x").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("x轴方位");
                    label.setAttribute("property","x");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                } else if ("series".equals(data.get("componentType"))) {
                    Iterator<Component> a = echartComp.queryAll("series").iterator();
                    List<Component> series = new ArrayList<>();
                    while (a.hasNext()) {
                        series.add(a.next());
                    }
                    selection = getElementByUuid(series.get(Integer.valueOf(data.get("seriesIndex") + "")).getUuid());
                    componentType = "series";
                    seriesIndex = data.get("seriesIndex") + "";
                    properties.getGroups().get(1).setOpen(true);
                    properties.getGroups().get(1).setLabel("模块属性(series)");
                    properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                    Row row = new Row();
                    Combobox combobox = new Combobox();
                    combobox.appendChild(new Comboitem("pie"));
                    combobox.appendChild(new Comboitem("bar"));
                    combobox.appendChild(new Comboitem("line"));
                    combobox.appendChild(new Comboitem("funnel"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("type") != null ? selection.getAttribute("type").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    Label label = new Label("类型");
                    label.setAttribute("property","type");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    Textbox textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("name") != null ? selection.getAttribute("name").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("名称");
                    label.setAttribute("property","name");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("dataArr") != null ? selection.getAttribute("dataArr").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("数据组");
                    label.setAttribute("property","dataArr");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("query") != null ? selection.getAttribute("query").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("查询语句");
                    label.setAttribute("property","query");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("stack") != null ? selection.getAttribute("stack").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("堆栈");
                    label.setAttribute("property","stack");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("selectedMode") != null ? selection.getAttribute("selectedMode").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("选中模式");
                    label.setAttribute("property","selectedMode");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("radius") != null ? selection.getAttribute("radius").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("半径");
                    label.setAttribute("property","radius");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("pie_inner"));
                    combobox.appendChild(new Comboitem("pie_rich"));
                    combobox.appendChild(new Comboitem("axis_format_percent"));
                    combobox.appendChild(new Comboitem("axis_format_temperature"));
                    combobox.appendChild(new Comboitem("funnel_default_percent"));
                    combobox.appendChild(new Comboitem("funnel_inside_percent"));
                    combobox.appendChild(new Comboitem("bar_visible_top"));
                    combobox.appendChild(new Comboitem("bar_visible_bottom"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("labelClass") != null ? selection.getAttribute("labelClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("标签风格");
                    label.setAttribute("property","labelClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("labelLine_hidden"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("labelLineClass") != null ? selection.getAttribute("labelLineClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("标签线风格");
                    label.setAttribute("property","labelLineClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("gauge_format_percent"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("detailClass") != null ? selection.getAttribute("detailClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("细节风格");
                    label.setAttribute("property","detailClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    combobox = new Combobox();
                    combobox.appendChild(new Comboitem("bar_markLine_minTomax"));
                    combobox.setHflex("1");
                    combobox.setValue(selection.getAttribute("markLineClass") != null ? selection.getAttribute("markLineClass").getValue() : "");
                    combobox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("标记线风格");
                    label.setAttribute("property","markLineClass");
                    row.appendChild(label);
                    row.appendChild(combobox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("itemOpacity") != null ? selection.getAttribute("itemOpacity").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("透明度");
                    label.setAttribute("property","itemOpacity");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("itemBorderWidth") != null ? selection.getAttribute("itemBorderWidth").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("边框宽度");
                    label.setAttribute("property","itemBorderWidth");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("itemBorderColor") != null ? selection.getAttribute("itemBorderColor").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("边框颜色");
                    label.setAttribute("property","itemBorderColor");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("itemBarBorderColor") != null ? selection.getAttribute("itemBarBorderColor").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("柱图边框颜色");
                    label.setAttribute("property","itemBarBorderColor");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                    row = new Row();
                    textbox = new Textbox();
                    textbox.setHflex("1");
                    textbox.setValue(selection.getAttribute("itemColor") != null ? selection.getAttribute("itemColor").getValue() : "");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    label = new Label("颜色");
                    label.setAttribute("property","itemColor");
                    row.appendChild(label);
                    row.appendChild(textbox);
                    row.setParent(properties);
                }
                if (isRepeat){
                    isRepeat = false;
                    Events.echoEvent(event);
                }
            }
            if (event.getName().equals(Events.ON_CHANGE)) {
                String propertyName = null;
                Object value = null;
                propertyName = ((Label) event.getTarget().getPreviousSibling()).getAttribute("property")+"";
                value = ((InputElement) event.getTarget()).getRawValue();
                Attribute attribute = selection.getAttribute(propertyName);
                if (attribute == null && value.toString().length() > 0) {
                    Attribute uuid = selection.getAttribute("uuid");
                    selection.removeAttribute(uuid);
                    selection.addAttribute(new Attribute(propertyName, value
                            .toString()));
                    // 保证uuid属性在最后
                    selection.addAttribute(uuid);
                } else if (attribute != null) {
                    if (value.equals(attribute.getValue()))
                        return;
                    attribute.setValue(value.toString());
                }
                //zulMapXml = CodeFormatter.formatXML(document);
                Document copy = (Document) document.copy();
                ZulXsdUtil.cleanUUIDs(copy.getRootElement());
                content = CodeFormatter.formatXML(copy);
                System.out.println(value);
                redraw();
                // TODO: 2019/8/23 这种方式判断来获取最新的selection以后要改掉
                if (Strings.isBlank(componentType)) {
                    return;
                }
                if (componentType.equals("xAxis")) {
                    selection = getElementByUuid(echartComp.query(componentType).getUuid());
                }else if (componentType.equals("yAxis")) {
                    selection = getElementByUuid(echartComp.query(componentType).getUuid());
                }else if (componentType.equals("legend")) {
                    selection = getElementByUuid(echartComp.query(componentType).getUuid());
                } else if (componentType.equals("series")) {
                    Iterator<Component> a = echartComp.queryAll(componentType).iterator();
                    List<Component> series = new ArrayList<>();
                    while (a.hasNext()) {
                        series.add(a.next());
                    }
                    selection = getElementByUuid(series.get(Integer.valueOf(seriesIndex)).getUuid());
                }
            }
        }
    }

    /**
     * 刷新Idspace(canvas)
     */
    public void redraw() {
        Component children = canvas.getFirstChild();
        if (children != null)
            children.detach();
        if (Strings.isBlank(content)) {
            if (document != null)
                document.detach();
            document = null;
        } else {
            echartComp = Executions.createComponentsDirectly(content,
                    "zul", canvas, null);
            document = mapZulToComponents(content, echartComp);
            if (scope.equals("bar")) {
                //echartComp.addEventListener(ECharts.ON_SELECTION, new BarEventListener());
            } else if (scope.equals("other")) {
                //echartComp.addEventListener(ECharts.ON_SELECTION, new OtherEventListener());
            }
        }
    }

    private Element getElementByUuid(final String uuid) {
        Nodes nodes = document.getRootElement()
                .query("descendant-or-self::*[@uuid='" + uuid + "']");
        if (nodes.size() > 0)
            return (Element) nodes.get(0);
        return null;
    }

    private Document mapZulToComponents(String content, final Component root) {
        Document document = ZulXsdUtil.buildDocument(content);
        if (document.getRootElement() == null)
            return document;

        Map<String, Object> params = new HashMap<String, Object>();
        ZulXsdUtil.traverseChildren(document.getRootElement(), params,
                new ChildDelegate<Element>() {
                    @Override
                    public void onChild(Element child,
                                        Map<String, Object> params) {
                        if (child.getParent() instanceof Document) {
                            if ("web".equals(child.getLocalName())) {
                                // 如果根元素是zk标签
                                child.addAttribute(new Attribute("uuid",
                                        "_canvas_"));
                            }
                        }
                        if ("web".equals(child.getLocalName()))
                            return;
                        else if ("zscript".equals(child.getLocalName())) {
                            // zsscript不是可显示的组件，但是通过给uuid就可以象正常的组件一样处理
                            child.addAttribute(new Attribute("uuid", "zscript_"
                                    + getNextUuid()));
                            return;
                        } else if ((ZulXsdUtil.isNative(child) && ZulXsdUtil
                                .isNative((Element) child.getParent()))
                                && (!hasNonNativeSiblings(child) || child
                                .getChildElements().size() == 0)) {
                            child.addAttribute(new Attribute("uuid", "native_"
                                    + getNextUuid()));
                            return;
                        }

                        Element parent = getParent(child);
                        if (parent == null) {
                            if (doMatch(child, root)) {
                                child.addAttribute(new Attribute("uuid", root
                                        .getUuid()));
                            }
                        } else {
                            String uuid = parent.getAttributeValue("uuid");
                            if (uuid != null) {
                                if (uuid.startsWith("native_")) {
                                    parent = (Element) parent.getParent();
                                    while (parent.getAttributeValue("uuid")
                                            .startsWith("native_")) {
                                        parent = (Element) parent.getParent();
                                    }
                                    uuid = parent.getAttributeValue("uuid");
                                }
                                Collection<Component> children = root.query(
                                        "[uuid^=\"" + uuid + "\"]")
                                        .getChildren();
                                for (Component comp : children) {
                                    if (doMatch(child, comp)) {
                                        child.addAttribute(new Attribute(
                                                "uuid", comp.getUuid()));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                });
        return document;
    }

    private String getNextUuid() {
        Desktop desktop = canvas.getDesktop();
        return ((DesktopCtrl) desktop).getNextUuid(desktop.getFirstPage());
    }

    private boolean hasNonNativeSiblings(Element element) {
        Node parent = element.getParent();
        if (!(parent instanceof Element))
            return false;

        for (int i = 0; i < ((Element) parent).getChildElements().size(); i++) {
            Element child = ((Element) parent).getChildElements().get(i);
            if (!child.equals(element) && !ZulXsdUtil.isNative(child)) {
                return true;
            }
        }
        return false;
    }

    private Element getParent(Element element) {
        Node parent = element.getParent();
        while (parent != null) {
            if (parent instanceof Element
                    && !"web".equals(((Element) parent).getLocalName())
                    && !"template".equals(((Element) parent).getLocalName())) {
                break;
            }
            parent = parent.getParent();
        }

        return parent instanceof Element ? (Element) parent : null;
    }

    private boolean doMatch(Element element, Component component) {
        boolean match;
        match = isAvailable(element.getDocument().getRootElement(),
                component.getUuid());
        if (!match)
            return false;
        if (component instanceof HtmlNativeComponent) {
            return element.getLocalName().equals(
                    ((HtmlNativeComponent) component).getTag())
                    && ZulXsdUtil.isNative(element);
        } else {
            return element.getLocalName().equals(
                    component.getDefinition().getName());
        }
    }

    private boolean isAvailable(Element root, String uuid) {
        // XPathContext xpathContext = new XPathContext("zul", ZUL_NS);
        Nodes nodes = root.query("//*[@uuid='" + uuid + "']", null);
        return nodes.size() == 0;
    }

    @Override
    public void onEvent(Event event) throws Exception {
        if (event.getName().equals(Events.ON_CLICK)) {//点击删除或增加的监听回调
            if (event.getTarget().getId().equals("echart_a_delete")) {//删除数据部分
                if (selection == null || Strings.isBlank(componentType) || !componentType.equals("series")) {
                    WebUtils.showInfo("请先点击图表选择对应的数据区域!");
                    return;
                }
                selection.detach();
                Document copy = (Document) document.copy();
                ZulXsdUtil.cleanUUIDs(copy.getRootElement());
                content = CodeFormatter.formatXML(copy);
                redraw();
                properties.getGroups().get(1).setLabel("模块属性");
                properties.getGroups().get(1).setOpen(false);
                properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                selection = null;
                componentType = null;
                seriesIndex = null;
                isRepeat = true;
            } else if (event.getTarget().getId().equals("echart_a_add")) {//增加数据部分
                new SerierWin(cb.getPage(), new OnSeriesListener() {
                    @Override
                    public void onSeries(String series) {
                        List<String> list = new ArrayList<>();
                        for (String line : content.split("\n")) {
                            list.add(line);
                        }
                        list.add(list.size() - 2, series.replace("\n", ""));
                        StringBuilder stringBuilder = new StringBuilder();
                        for (String line : list) {
                            stringBuilder.append(line + "\n");
                        }
                        content = stringBuilder.toString();
                        redraw();
                        properties.getGroups().get(1).setLabel("模块属性");
                        properties.getGroups().get(1).setOpen(false);
                        properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                        selection = null;
                        componentType = null;
                        seriesIndex = null;
                        isRepeat = true;
                    }
                }).doHighlighted();
            } else if (event.getTarget().getId().equals("echart_btn_save")) {//点击保存
                cb.setValue(content);
                event.getTarget().getRoot().detach();
            } else if (event.getTarget().getId().equals("echart_btn_cancel")) {//点击取消
                event.getTarget().getRoot().detach();
            } else if (event.getTarget().getId().equals("echart_a_replace")){//点击模板
                AbstractView.createSelectEchartView(new EditorCallback<String>() {
                    @Override
                    public String getValue() {
                        return "";
                    }

                    @Override
                    public void setValue(String value) {
                        try {
                            content = IOUtils.toString(Locators.getDefault()
                                    .getResourceAsStream("web/template/" + value + ".zul"),"utf-8");
                            redraw();
                            id.setValue(((ECharts) echartComp).getId());
                            //title.setValue(((ECharts) echartComp).getTitle());
                            theme.setValue(((ECharts) echartComp).getTheme());
                            String toolStr = ((ECharts) echartComp).getToolbox() != null ? ((ECharts) echartComp).getToolbox() : "";
                            toolbox.setSelectedObjects(Arrays.asList(toolStr.split(";")));
                            hflex.setValue(((ECharts) echartComp).getHflex() != null ? ((ECharts) echartComp).getHflex() : "");
                            vflex.setValue(((ECharts) echartComp).getVflex() != null ? ((ECharts) echartComp).getVflex() : "");
                            top.setValue(((ECharts) echartComp).getTop() != null ? ((ECharts) echartComp).getTop() : "");
                            //bottom.setValue(((ECharts) echartComp).getBottom() != null ? ((ECharts) echartComp).getBottom() : "");
                            left.setValue(((ECharts) echartComp).getLeft() != null ? ((ECharts) echartComp).getLeft() : "");
                            //right.setValue(((ECharts) echartComp).getRight() != null ? ((ECharts) echartComp).getRight() : "");
                            properties.getGroups().get(1).setLabel("模块属性");
                            properties.getGroups().get(1).setOpen(false);
                            properties.getChildren().removeAll(properties.getGroups().get(1).getItems());
                            selection = null;
                            componentType = null;
                            seriesIndex = null;
                            isRepeat = true;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public String getTitle() {
                        return "选择图表模板";
                    }

                    @Override
                    public Page getPage() {
                        return cb.getPage();
                    }

                    @Override
                    public Editor getEditor() {
                        return null;
                    }
                },"click").doHighlighted();
            }
        }
        if (event.getName().equals(Events.ON_CHANGE)||event.getName().equals(Events.ON_SELECT)) {//基础属性配置框数值改变时
            // TODO: 2019/8/26 用于公共属性的监听
            Object val = null;
            if (event.getTarget() instanceof Chosenbox){
                SelectEvent selectEvent = (SelectEvent) event;
                if (selectEvent.getSelectedObjects().size()==0)
                    val = "";
                else{
                    Set<String> stringSet = selectEvent.getSelectedObjects();
                    String selStr = "";
                    for (String str:stringSet){
                        selStr += str+";";
                    }
                    val = selStr.substring(0,selStr.length()-1);
                }
            } else {
                val = ((InputElement) event.getTarget()).getRawValue();
            }
            // TODO: 2019/8/22 下面是一段用于改值得核心代码，到时候领出去写
            Element select = getElementByUuid(echartComp.getUuid());
            Component component = event.getTarget().getPreviousSibling();
            Attribute attribute = select.getAttribute(((Label) event.getTarget().getPreviousSibling()).getAttribute("property")+"");
            if (attribute == null && val.toString().length() > 0) {
                Attribute uuid = select.getAttribute("uuid");
                select.removeAttribute(uuid);
                select.addAttribute(new Attribute(((Label) event.getTarget().getPreviousSibling()).getAttribute("property")+"", val
                        .toString()));
                // 保证uuid属性在最后
                select.addAttribute(uuid);
            } else if (attribute != null) {
                if (val.equals(attribute.getValue()))
                    return;
                attribute.setValue(val.toString());
            }
            //attribute.setValue(val + "");
            //zulMapXml = CodeFormatter.formatXML(document);
            Document copy = (Document) document.copy();
            ZulXsdUtil.cleanUUIDs(copy.getRootElement());
            content = CodeFormatter.formatXML(copy);
            redraw();
            // TODO: 2019/8/23 这种方式判断来获取最新的selection以后要改掉
            if (Strings.isBlank(componentType)) {
                return;
            }
            if (componentType.equals("xAxis")) {
                selection = getElementByUuid(echartComp.query(componentType).getUuid());
            } else if (componentType.equals("yAxis")) {
                selection = getElementByUuid(echartComp.query(componentType).getUuid());
            } else if (componentType.equals("series")) {
                Iterator<Component> a = echartComp.queryAll(componentType).iterator();
                List<Component> series = new ArrayList<>();
                while (a.hasNext()) {
                    series.add(a.next());
                }
                selection = getElementByUuid(series.get(Integer.valueOf(seriesIndex)).getUuid());
            }
        }
    }

    private interface OnSeriesListener {//增加数据窗口,点击确定数据回调接口

        void onSeries(String series);
    }

    //Serier增加数据弹框类
    private class SerierWin implements EventListener<Event> {
        private Window seriesWin;
        private Grid grid;
        private Page page;
        private OnSeriesListener onSeriesListener;

        public SerierWin(Page page, OnSeriesListener onSeriesListener) {
            this.onSeriesListener = onSeriesListener;
            this.page = page;
        }

        public void doHighlighted() {
            seriesWin = new Window();
            seriesWin.setClosable(true);
            seriesWin.setPage(page);
            seriesWin.setPosition("center");
            seriesWin.setBorder("normal");
            seriesWin.setTitle("增加数据");
            seriesWin.setHeight("420px");
            seriesWin.setWidth("250px");
            Vlayout vlayout = new Vlayout();
            vlayout.setVflex("1");
            vlayout.setHflex("1");
            vlayout.setParent(seriesWin);
            Toolbar toolbar = new Toolbar();
            toolbar.appendChild(new Label("Series:"));
            toolbar.setParent(vlayout);
            grid = new Grid();
            grid.setVflex("1");
            grid.setHflex("1");
            grid.appendChild(new Columns());
            grid.appendChild(new Rows());
            Column column = new Column();
            column.setWidth("30%");
            grid.getColumns().appendChild(column);
            column = new Column();
            column.setWidth("50%");
            grid.getColumns().appendChild(column);
            Rows rows = grid.getRows();
            Row row = new Row();
            Combobox combobox = new Combobox();
            combobox.appendChild(new Comboitem("pie"));
            combobox.appendChild(new Comboitem("bar"));
            combobox.appendChild(new Comboitem("line"));
            combobox.appendChild(new Comboitem("funnel"));
            combobox.setHflex("1");
            combobox.setId("seriesWin_type");
            row.appendChild(new Label("类型"));
            row.appendChild(combobox);
            row.setParent(rows);
            row = new Row();
            Textbox textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_name");
            row.appendChild(new Label("名称"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_dataArr");
            row.appendChild(new Label("数据组"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_query");
            row.appendChild(new Label("查询语句"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_stack");
            row.appendChild(new Label("堆栈"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_selectedMode");
            row.appendChild(new Label("选中模式"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            textbox = new Textbox();
            textbox.setHflex("1");
            textbox.setId("seriesWin_radius");
            row.appendChild(new Label("半径"));
            row.appendChild(textbox);
            row.setParent(rows);
            row = new Row();
            combobox = new Combobox();
            combobox.appendChild(new Comboitem("pie_inner"));
            combobox.appendChild(new Comboitem("pie_rich"));
            combobox.appendChild(new Comboitem("axis_format_percent"));
            combobox.appendChild(new Comboitem("axis_format_temperature"));
            combobox.appendChild(new Comboitem("funnel_default_percent"));
            combobox.appendChild(new Comboitem("funnel_inside_percent"));
            combobox.setHflex("1");
            combobox.setId("seriesWin_labelClass");
            row.appendChild(new Label("标签风格"));
            row.appendChild(combobox);
            row.setParent(rows);
            row = new Row();
            combobox = new Combobox();
            combobox.appendChild(new Comboitem("labelLine_hidden"));
            combobox.setHflex("1");
            combobox.setId("seriesWin_labelLineClass");
            row.appendChild(new Label("标签线风格"));
            row.appendChild(combobox);
            row.setParent(rows);
            row = new Row();
            combobox = new Combobox();
            combobox.appendChild(new Comboitem("gauge_format_percent"));
            combobox.setHflex("1");
            combobox.setId("seriesWin_detailClass");
            row.appendChild(new Label("细节风格"));
            row.appendChild(combobox);
            row.setParent(rows);
            row = new Row();
            combobox = new Combobox();
            combobox.appendChild(new Comboitem("bar_markLine_minTomax"));
            combobox.setHflex("1");
            combobox.setId("seriesWin_markLineClass");
            row.appendChild(new Label("标记线风格"));
            row.appendChild(combobox);
            row.setParent(rows);
            grid.setParent(vlayout);
            Hlayout hlayout = new Hlayout();
            hlayout.setStyle("padding-bottom:3px");
            hlayout.setHflex("1");
            Div div = new Div();
            div.setHflex("1");
            div.setParent(hlayout);
            Button button = new Button();
            button.setLabel("确定");
            button.setSclass("pull-right epstudio-top");
            button.setIconSclass("z-icon-check");
            button.addEventListener(Events.ON_CLICK, this);
            hlayout.appendChild(button);
            hlayout.setParent(vlayout);
            seriesWin.doHighlighted();
        }

        private void setAttributeValue(Element ele, String propertyName, String value) {
            Attribute attribute = ele.getAttribute(propertyName);
            if (attribute == null && value.toString().length() > 0) {
                Attribute uuid = ele.getAttribute("uuid");
                ele.removeAttribute(uuid);
                ele.addAttribute(new Attribute(propertyName, value
                        .toString()));
                // 保证uuid属性在最后
                ele.addAttribute(uuid);
            } else if (attribute != null && value.toString().length() > 0) {
                if (value.equals(attribute.getValue()))
                    return;
                attribute.setValue(value.toString());
            }
        }

        @Override
        public void onEvent(Event event) throws Exception {
            // TODO: 2019/8/26 这个逻辑的变量要改掉不要付给全局变量
            Component seriesComp = Executions.createComponentsDirectly("<series/>",
                    "zul", seriesWin, null);
            Document seriesDoc = mapZulToComponents("<series/>", seriesComp);
            Element seriesEle = null;
            Nodes nodes = seriesDoc.getRootElement()
                    .query("descendant-or-self::*[@uuid='" + seriesComp.getUuid() + "']");
            if (nodes.size() > 0)
                seriesEle = (Element) nodes.get(0);
            else
                seriesEle = null;
            for (Component comp : grid.getFellows()) {
                if (comp instanceof Textbox) {
                    if (Strings.isBlank(((Textbox) comp).getValue()))
                        continue;
                    if (comp.getId().equals("seriesWin_type")) {
                        setAttributeValue(seriesEle, "type", ((Textbox) comp).getValue());
                    } else if (comp.getId().equals("seriesWin_name")) {
                        setAttributeValue(seriesEle, "name", ((Textbox) comp).getValue());
                    } else if (comp.getId().equals("seriesWin_dataArr")) {
                        setAttributeValue(seriesEle, "dataArr", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_query")) {
                        setAttributeValue(seriesEle, "query", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_stack")) {
                        setAttributeValue(seriesEle, "stack", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_selectedMode")) {
                        setAttributeValue(seriesEle, "selectedMode", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_radius")) {
                        setAttributeValue(seriesEle, "radius", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_labelClass")) {
                        setAttributeValue(seriesEle, "labelClass", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_labelLineClass")) {
                        setAttributeValue(seriesEle, "labelLineClass", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_detailClass")) {
                        setAttributeValue(seriesEle, "detailClass", ((Textbox) comp).getValue());
                    }else if (comp.getId().equals("seriesWin_markLineClass")) {
                        setAttributeValue(seriesEle, "markLineClass", ((Textbox) comp).getValue());
                    }
                }
            }
            if (seriesEle.getAttributeCount() != 1) {
                ZulXsdUtil.cleanUUIDs(seriesDoc.getRootElement());
                onSeriesListener.onSeries(CodeFormatter.formatXML(seriesDoc));
            }
            seriesWin.detach();
        }
    }

}
